﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using Cloak.Reflection;

namespace Ruleweaver.Rules.CheckMethods
{
	public sealed class MatchesMethod : SingleTypeCheckMethod
	{
		private readonly Regex _regex;
		private readonly string _pattern;
		private readonly RegexOptions? _options;

		public MatchesMethod(Regex regex)
		{
			Contract.Requires(regex != null);

			_regex = regex;
		}

		public MatchesMethod(string pattern)
		{
			Contract.Requires(pattern != null);

			_pattern = pattern;
		}

		public MatchesMethod(string pattern, RegexOptions options) : this(pattern)
		{
			_options = options;
		}

		protected override Type TargetType
		{
			get { return typeof(string); }
		}

		protected override MethodInfo GetMethod(Type checkType)
		{
			if(_regex != null)
			{
				return Reflect.Func<ICheckable<string>, Regex, Check<string>>(Checkable.Matches);
			}
			else if(_options != null)
			{
				return Reflect.Func<ICheckable<string>, string, RegexOptions, Check<string>>(Checkable.Matches);
			}
			else
			{
				return Reflect.Func<ICheckable<string>, string, Check<string>>(Checkable.Matches);
			}
		}

		protected override IEnumerable<object> GetCheckArguments()
		{
			if(_regex != null)
			{
				yield return _regex;
			}
			else
			{
				yield return _pattern;

				if(_options != null)
				{
					yield return _options.Value;
				}
			}
		}
	}
}